home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1995 Free Software Foundation, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * As a special exception, the Free Software Foundation gives permission
- * for additional uses of the text contained in its release of GUILE.
- *
- * The exception is that, if you link the GUILE library with other files
- * to produce an executable, this does not by itself cause the
- * resulting executable to be covered by the GNU General Public License.
- * Your use of that executable is in no way restricted on account of
- * linking the GUILE library code into it.
- *
- * This exception does not however invalidate any other reasons why
- * the executable file might be covered by the GNU General Public License.
- *
- * This exception applies only to the code released by the
- * Free Software Foundation under the name GUILE. If you copy
- * code from other Free Software Foundation releases into a copy of
- * GUILE, as the General Public License permits, the exception does
- * not apply to the code that you add in this way. To avoid misleading
- * anyone as to the status of such modified files, you must delete
- * this exception notice from them.
- *
- * If you write modifications of your own for GUILE, it is your choice
- * whether to permit this exception to apply to your modifications.
- * If you do not wish that, delete this exception notice.
- */
-
-
- #include <stdio.h>
- #include "_scm.h"
-
-
-
- SCM scm_sys_protects[NUM_PROTECTS];
- sizet scm_num_protects = NUM_PROTECTS;
-
- /* If fewer than MIN_GC_YIELD cells are recovered during a garbage
- * collection (GC) more space is allocated for the heap.
- */
- #define MIN_GC_YIELD (scm_heap_size/4)
-
-
-
-
- /* {Front end to malloc}
- *
- * scm_must_malloc, scm_must_realloc, scm_must_free
- *
- * These functions provide services comperable to malloc, realloc, and
- * free. They are for allocating malloced parts of scheme objects.
- * The primary purpose of the front end is to impose calls to gc.
- */
-
- /* scm_mtrigger
- * is the number of bytes of must_malloc allocation needed to trigger gc.
- */
- long scm_mtrigger;
-
- /* scm_grew_lim
- * is called whenever the must_malloc limit that triggers garbage collection
- * is raised. The limit is raised if a garbage collection followed
- * by a subsequent allocation fails to reduce allocated storage below
- * the limit.
- */
- #ifdef __STDC__
- void
- scm_grew_lim (long nm)
- #else
- void
- scm_grew_lim (nm)
- long nm;
- #endif
- {
- ALLOW_INTS;
- scm_growth_mon ("limit", nm, "bytes");
- DEFER_INTS;
- }
-
- /* scm_must_malloc
- * Return newly malloced storage or throw an error.
- *
- * The parameter WHAT is a string for error reporting.
- * If the threshold scm_mtrigger will be passed by this
- * allocation, or if the first call to malloc fails,
- * garbage collect -- on the presumption that some objects
- * using malloced storage may be collected.
- *
- * The limit scm_mtrigger may be raised by this allocation.
- */
- #ifdef __STDC__
- char *
- scm_must_malloc (long len, char *what)
- #else
- char *
- scm_must_malloc (len, what)
- long len;
- char *what;
- #endif
- {
- char *ptr;
- sizet size = len;
- long nm = scm_mallocated + size;
- if (len != size)
- malerr:
- scm_wta (MAKINUM (len), (char *) NALLOC, what);
- if ((nm <= scm_mtrigger))
- {
- SYSCALL (ptr = (char *) malloc (size));
- if (NULL != ptr)
- {
- scm_mallocated = nm;
- return ptr;
- }
- }
- scm_igc (what);
- nm = scm_mallocated + size;
- if (nm > scm_mtrigger)
- scm_grew_lim (nm + nm / 2); /* must do before malloc */
- SYSCALL (ptr = (char *) malloc (size));
- if (NULL != ptr)
- {
- scm_mallocated = nm;
- if (nm > scm_mtrigger)
- scm_mtrigger = nm + nm / 2;
- return ptr;
- }
- goto malerr;
- }
-
-
- /* scm_must_realloc
- * is similar to scm_must_malloc.
- */
- #ifdef __STDC__
- char *
- scm_must_realloc (char *where, long olen, long len, char *what)
- #else
- char *
- scm_must_realloc (where, olen, len, what)
- char *where;
- long olen;
- long len;
- char *what;
- #endif
- {
- char *ptr;
- sizet size = len;
- long nm = scm_mallocated + size - olen;
- if (len != size)
- ralerr:
- scm_wta (MAKINUM (len), (char *) NALLOC, what);
- if ((nm <= scm_mtrigger))
- {
- SYSCALL (ptr = (char *) realloc (where, size));
- if (NULL != ptr)
- {
- scm_mallocated = nm;
- return ptr;
- }
- }
- scm_igc (what);
- nm = scm_mallocated + size - olen;
- if (nm > scm_mtrigger)
- scm_grew_lim (nm + nm / 2); /* must do before realloc */
- SYSCALL (ptr = (char *) realloc (where, size));
- if (NULL != ptr)
- {
- scm_mallocated = nm;
- if (nm > scm_mtrigger)
- scm_mtrigger = nm + nm / 2;
- return ptr;
- }
- goto ralerr;
- }
-
- /* scm_must_free
- * is for releasing memory from scm_must_realloc and scm_must_malloc.
- */
- #ifdef __STDC__
- void
- scm_must_free (char *obj)
- #else
- void
- scm_must_free (obj)
- char *obj;
- #endif
- {
- if (obj)
- free (obj);
- else
- scm_wta (INUM0, "already free", "");
- }
-
-
-
-
- /* {Heap Segments}
- *
- * Each heap segment is an array of objects of a particular size.
- * Every segment has an associated (possibly shared) freelist.
- * A table of segment records is kept that records the upper and
- * lower extents of the segment; this is used during the conservative
- * phase of gc to identify probably gc roots (because they point
- * into valid segments at reasonable offsets).
- */
-
- /* scm_expmem
- * is true if the first segment was smaller than INIT_HEAP_SEG.
- * If scm_expmem is set to one, subsequent segment allocations will
- * allocate segments of size EXPHEAP(scm_heap_size).
- */
- int scm_expmem = 0;
-
- /* scm_heap_org
- * is the lowest base address of any heap segment.
- */
- CELLPTR scm_heap_org;
-
- struct scm_heap_seg_data * scm_heap_table = 0;
- int scm_n_heap_segs = 0;
-
- /* scm_heap_size
- * is the total number of cells in heap segments.
- */
- long scm_heap_size = 0;
-
- /* init_heap_seg
- * initializes a new heap segment and return the number of objects it contains.
- *
- * The segment origin, segment size in bytes, and the span of objects
- * in cells are input parameters. The freelist is both input and output.
- *
- * This function presume that the scm_heap_table has already been expanded
- * to accomodate a new segment record.
- */
-
-
- #ifdef __STDC__
- static sizet
- init_heap_seg (CELLPTR seg_org, sizet size, int ncells, SCM *freelistp)
- #else
- static sizet
- init_heap_seg (seg_org, size, ncells, freelistp)
- CELLPTR seg_org;
- sizet size;
- int ncells;
- SCM *freelistp;
- #endif
- {
- register CELLPTR ptr;
- #ifdef POINTERS_MUNGED
- register SCM scmptr;
- #else
- #define scmptr ptr
- #endif
- CELLPTR seg_end;
- sizet new_seg_index;
- sizet n_new_objects;
-
- if (seg_org == NULL)
- return 0;
-
- ptr = seg_org;
-
- /* Compute the ceiling on valid object pointers w/in this segment.
- */
- seg_end = CELL_DN ((char *) ptr + size);
-
- /* Find the right place and insert the segment record.
- *
- */
- for (new_seg_index = 0;
- ( (new_seg_index < scm_n_heap_segs)
- && PTR_LE (scm_heap_table[new_seg_index].bounds[0], seg_org));
- new_seg_index++)
- ;
-
- {
- int i;
- for (i = scm_n_heap_segs; i > new_seg_index; --i)
- scm_heap_table[i] = scm_heap_table[i - 1];
- }
-
- ++scm_n_heap_segs;
-
- scm_heap_table[new_seg_index].valid = 0;
- scm_heap_table[new_seg_index].ncells = ncells;
- scm_heap_table[new_seg_index].freelistp = freelistp;
- scm_heap_table[new_seg_index].bounds[0] = (CELLPTR)ptr;
- scm_heap_table[new_seg_index].bounds[1] = (CELLPTR)seg_end;
-
-
- /* Compute the least valid object pointer w/in this segment
- */
- ptr = CELL_UP (ptr);
-
-
- n_new_objects = seg_end - ptr;
-
- /* Prepend objects in this segment to the freelist.
- */
- while (ptr < seg_end)
- {
- #ifdef POINTERS_MUNGED
- scmptr = PTR2SCM (ptr);
- #endif
- CAR (scmptr) = (SCM) tc_free_cell;
- CDR (scmptr) = PTR2SCM (ptr + ncells);
- ptr += ncells;
- }
-
- ptr -= ncells;
-
- /* Patch up the last freelist pointer in the segment
- * to join it to the input freelist.
- */
- CDR (PTR2SCM (ptr)) = *freelistp;
- *freelistp = PTR2SCM (CELL_UP (seg_org));
-
- scm_heap_size += (ncells * n_new_objects);
- return size;
- #ifdef scmptr
- #undef scmptr
- #endif
- }
-
-
- static char scm_s_nogrow[] = "could not grow";
- char scm_s_heap[] = "heap";
- static char scm_s_hplims[] = "hplims";
-
- #ifdef __STDC__
- static void
- alloc_some_heap (int ncells, SCM * freelistp)
- #else
- static void
- alloc_some_heap (ncells, freelistp)
- int ncells;
- SCM * freelistp;
- #endif
- {
- struct scm_heap_seg_data * tmptable;
- CELLPTR ptr;
- sizet len;
-
- /* Critical code sections (such as the garbage collector)
- * aren't supposed to add heap segments.
- */
- if (scm_errjmp_bad)
- scm_wta (SCM_UNDEFINED, "need larger initial", scm_s_heap);
-
- /* Expand the heap tables to have room for the new segment.
- * Do not yet increment scm_n_heap_segs -- that is done by init_heap_seg
- * only if the allocation of the segment itself succeeds.
- */
- len = (1 + scm_n_heap_segs) * sizeof (struct scm_heap_seg_data);
-
- SYSCALL (tmptable = ((struct scm_heap_seg_data *)
- realloc ((char *)scm_heap_table, len)));
- if (!tmptable)
- scm_wta (SCM_UNDEFINED, scm_s_nogrow, scm_s_hplims);
- else
- scm_heap_table = tmptable;
-
-
- /* Pick a size for the new heap segment.
- * The rule for picking the size of a segment is explained in
- * (for some reason) setjump.h (c.f. {heap parameters}).
- */
- if (scm_expmem)
- {
- len = (sizet) (EXPHEAP (scm_heap_size) * sizeof (scm_cell));
- if ((sizet) (EXPHEAP (scm_heap_size) * sizeof (scm_cell)) != len)
- len = 0;
- }
- else
- len = HEAP_SEG_SIZE;
-
- {
- sizet smallest;
-
- smallest = (ncells * sizeof (scm_cell));
- if (len < smallest)
- len = (ncells * sizeof (scm_cell));
-
- /* Allocate with decaying ambition. */
- while ((len >= MIN_HEAP_SEG_SIZE)
- && (len >= smallest))
- {
- SYSCALL (ptr = (CELLPTR) malloc (len));
- if (ptr)
- {
- init_heap_seg (ptr, len, ncells, freelistp);
- return;
- }
- len /= 2;
- }
- }
-
- scm_wta (SCM_UNDEFINED, scm_s_nogrow, scm_s_heap);
- }
-
-
-
-
- #ifdef __STDC__
- void
- scm_permenant_object (SCM obj)
- #else
- void
- scm_permenant_object (obj)
- SCM obj;
- #endif
- {
- permobjs = scm_cons (obj, permobjs);
- }
-
-
-
- /* {Object allocation}
- */
-
- /* scm_moderate_freelists
- * is a table of freelists for object sizes less than SCM_MODERATE.
- */
- #ifndef SCM_MODERATE
- #define SCM_MODERATE 256
- #endif
-
- static SCM scm_moderate_freelists[SCM_MODERATE] = { (SCM)EOL };
-
- /* scm_large_objects
- * a circular, doubly linked list of large objects.
- */
- static scm_cell scm_large_objects
- = { (SCM)&scm_large_objects, (SCM)&scm_large_objects };
-
- struct large_obj_header
- {
- scm_cell link;
- int size;
- };
-
- #ifdef __STDC__
- SCM
- scm_alloc_large (int ncells, char * reason)
- #else
- SCM
- scm_alloc_large (ncells, reason)
- int ncells;
- char * reason;
- #endif
- {
- int bytes;
- struct large_obj_header * mem;
- SCM answer;
-
- bytes = ( (sizeof (scm_cell) * ncells)
- + sizeof(struct large_obj_header));
- mem = (struct large_obj_header *)scm_must_malloc (bytes, "large reason");
- answer = (SCM)(mem + 1);
-
- DEFER_INTS;
- CAR(answer) = (SCM)tc_free_cell;
- CDR(answer) = (SCM)EOL;
- ALLOW_INTS;
-
- {
- int x;
- for (x = 0; x < ncells; ++x)
- ((SCM *)answer)[x] = BOOL_F;
- }
-
- mem->size = bytes;
-
- mem->link.car = scm_large_objects.car;
- mem->link.cdr = (SCM)&scm_large_objects;
- CDR(mem->link.car) = (SCM)&(mem->link);
- scm_large_objects.car = (SCM)&(mem->link);
-
- return answer;
- }
- #if 0
- #ifdef __STDC__
- static int
- free_large (SCM obj)
- #else
- static int
- free_large (obj)
- SCM obj;
- #endif
- {
- struct large_obj_header * mem;
- mem = (struct large_obj_header *)obj;
- mem -= 1;
- CDR(mem->link.car) = mem->link.cdr;
- CAR(mem->link.cdr) = mem->link.car;
- {
- int bytes;
- bytes = mem->size;
- scm_must_free ((char *)mem);
- return bytes;
- }
- }
- #endif
- /* {Malloc-like allocation for Scheme objects of aribitrary size}
- * These can not be resized.
- */
-
- char scm_s_cells[] = "cells";
- #ifdef __STDC__
- void
- scm_gc_for_alloc (int ncells, SCM * freelistp)
- #else
- void
- scm_gc_for_alloc (ncells, freelistp)
- int ncells;
- SCM * freelistp;
- #endif
- {
- REDEFER_INTS;
- scm_igc (scm_s_cells);
- REALLOW_INTS;
- if ((scm_gc_cells_collected < MIN_GC_YIELD) || IMP (*freelistp))
- {
- REDEFER_INTS;
- alloc_some_heap (ncells, freelistp);
- REALLOW_INTS;
- if (!scm_ints_disabled) /* !!! */
- {
- scm_growth_mon ("number of heaps",
- (long) scm_n_heap_segs,
- "segments");
- scm_growth_mon (scm_s_heap, scm_heap_size, scm_s_cells);
- }
- }
- }
-
- #ifdef __STDC__
- SCM
- scm_alloc_obj (SCM ncells, char * reason)
- #else
- SCM
- scm_alloc_obj (ncells, reason)
- SCM ncells;
- char * reason;
- #endif
- {
- if (ncells > SCM_MODERATE)
- return scm_alloc_large (ncells, reason);
- else
- {
- SCM answer;
- answer = scm_moderate_freelists[ncells];
- if (answer == EOL)
- scm_gc_for_alloc (ncells, &scm_moderate_freelists[ncells]);
- answer = scm_moderate_freelists[ncells];
- scm_moderate_freelists[ncells] = CDR (scm_moderate_freelists[ncells]);
- return answer;
- }
- }
-
-
- /* {Initialization for i/o and gc procedures.}
- */
-
- char scm_s_obunhash[] = "object-unhash";
-
- #ifdef __STDC__
- void
- scm_init_io (void)
- #else
- void
- scm_init_io ()
- #endif
- {
- #ifndef CHEAP_CONTINUATIONS
- scm_add_feature ("full-continuation");
- #endif
- }
-
-
- /* {cons pair allocation}
- */
-
- /* scm_freelist
- * is the head of freelist of cons pairs.
- */
- SCM scm_freelist = EOL;
-
- /* scm_gc_for_newcell
- *
- * Still resides below under the PARADIGM ASSOCIATES copyright.
- */
-
-
- /* {GC marking}
- */
-
- #ifdef __STDC__
- SCM
- scm_markcdr (SCM ptr)
- #else
- SCM
- scm_markcdr (ptr)
- SCM ptr;
- #endif
- {
- if (GC8MARKP (ptr))
- return BOOL_F;
- SETGC8MARK (ptr);
- return CDR (ptr);
- }
-
- #ifdef __STDC__
- SCM
- scm_mark0 (SCM ptr)
- #else
- SCM
- scm_mark0 (ptr)
- SCM ptr;
- #endif
- {
- SETGC8MARK (ptr);
- return BOOL_F;
- }
-
- #ifdef __STDC__
- sizet
- scm_free0 (SCM ptr)
- #else
- sizet
- scm_free0 (ptr)
- SCM ptr;
- #endif
- {
- return 0;
- }
-
- #ifdef __STDC__
- SCM
- scm_equal0 (SCM ptr1, SCM ptr2)
- #else
- SCM
- scm_equal0 (ptr1, ptr2)
- SCM ptr1;
- SCM ptr2;
- #endif
- {
- return (CDR (ptr1) == CDR (ptr2)) ? BOOL_T : BOOL_F;
- }
-
-
- /* statically allocated port for diagnostic messages */
- scm_cell scm_tmp_errp =
- {(SCM) ((0L << 8) | tc16_fport | OPN | WRTNG), 0};
-
- static char remsg[] = "remove\n#define ", addmsg[] = "add\n#define ";
- extern sizet scm_num_protects; /* scm_sys_protects now in scl.c */
-
-
- #ifdef __STDC__
- static void
- fixconfig (char *s1, char *s2, int s)
- #else
- static void
- fixconfig (s1, s2, s)
- char *s1;
- char *s2;
- int s;
- #endif
- {
- fputs (s1, stderr);
- fputs (s2, stderr);
- fputs ("\nin ", stderr);
- fputs (s ? "setjump" : "scmfig", stderr);
- fputs (".h and recompile scm\n", stderr);
- scm_quit (MAKINUM (1L));
- }
-
- int scm_take_stdin = 0;
-
- #ifdef __STDC__
- void
- scm_init_storage (SCM_STACKITEM *stack_start_ptr, long init_heap_size, FILE * in, FILE * out, FILE * err)
- #else
- void
- scm_init_storage (stack_start_ptr, init_heap_size, in, out, err)
- SCM_STACKITEM *stack_start_ptr;
- long init_heap_size;
- FILE * in;
- FILE * out;
- FILE * err;
- #endif
- {
- sizet j = scm_num_protects;
- /* Because not all protects may get initialized */
- while (j)
- scm_sys_protects[--j] = BOOL_F;
- scm_tmp_errp.cdr = (SCM) stderr;
- cur_errp = PTR2SCM (&scm_tmp_errp);
- scm_freelist = EOL;
- scm_expmem = 0;
-
- #ifdef SINGLES
- if (sizeof (float) != sizeof (long))
- fixconfig (remsg, "SINGLES", 0);
- #endif /* def SINGLES */
- #ifdef BIGDIG
- if (2 * BITSPERDIG / CHAR_BIT > sizeof (long))
- fixconfig (remsg, "BIGDIG", 0);
- #ifndef DIGSTOOBIG
- if (DIGSPERLONG * sizeof (BIGDIG) > sizeof (long))
- fixconfig (addmsg, "DIGSTOOBIG", 0);
- #endif
- #endif
- #ifdef STACK_GROWS_UP
- if (((STACKITEM *) & j - stack_start_ptr) < 0)
- fixconfig (remsg, "STACK_GROWS_UP", 1);
- #else
- if ((stack_start_ptr - (STACKITEM *) & j) < 0)
- fixconfig (addmsg, "STACK_GROWS_UP", 1);
- #endif
- j = HEAP_SEG_SIZE;
- if (HEAP_SEG_SIZE != j)
- fixconfig ("reduce", "size of HEAP_SEG_SIZE", 0);
-
- scm_mtrigger = INIT_MALLOC_LIMIT;
- scm_heap_table = ((struct scm_heap_seg_data *)
- scm_must_malloc (sizeof (struct scm_heap_seg_data),
- scm_s_hplims));
- if (0L == init_heap_size)
- init_heap_size = INIT_HEAP_SIZE;
- j = init_heap_size;
- if ((init_heap_size != j)
- || !init_heap_seg ((CELLPTR) malloc (j), j, 1, &scm_freelist))
- {
- j = HEAP_SEG_SIZE;
- if (!init_heap_seg ((CELLPTR) malloc (j), j, 1, &scm_freelist))
- scm_wta (MAKINUM (j), (char *) NALLOC, scm_s_heap);
- }
- else
- scm_expmem = 1;
- scm_heap_org = CELL_UP (scm_heap_table[0].bounds[0]);
- /* scm_hplims[0] can change. do not remove scm_heap_org */
-
- /* Initialise the list of ports. */
- scm_port_table = (struct scm_port_table *)
- scm_must_malloc ((long) (sizeof (struct scm_port_table)
- * scm_port_table_room),
- "port list");
- /* Initialise standard ports. */
- NEWCELL (def_inp);
- if (scm_take_stdin && !in)
- in = stdin;
- if (in)
- {
- CAR (def_inp) = (tc16_fport | OPN | RDNG);
- SETSTREAM (def_inp, in);
- if (isatty (fileno (in)))
- {
- scm_setbuf0 (def_inp); /* turn off stdin buffering */
- CAR (def_inp) |= BUF0;
- }
- scm_add_to_port_table (def_inp);
- scm_set_port_revealed_x (def_inp, MAKINUM (1));
- }
- else
- {
- SCM str;
- str = scm_makfromstr ("", 0, 0);
- CAR (def_inp) = (tc16_strport | OPN | RDNG);
- SETCHARS (def_inp, str);
- }
- if (!out)
- out = stdout;
- NEWCELL (def_outp);
- CAR (def_outp) = (tc16_fport | OPN | WRTNG);
- SETSTREAM (def_outp, out);
- scm_add_to_port_table (def_outp);
- scm_set_port_revealed_x (def_outp, MAKINUM (1));
- NEWCELL (def_errp);
- if (!err)
- err = stderr;
- CAR (def_errp) = (tc16_fport | OPN | WRTNG);
- SETSTREAM (def_errp, err);
- scm_add_to_port_table (def_errp);
- scm_set_port_revealed_x (def_errp, MAKINUM (1));
- cur_inp = def_inp;
- cur_outp = def_outp;
- cur_errp = def_errp;
- dynwinds = EOL;
- NEWCELL (rootcont);
- SETJMPBUF (rootcont, scm_must_malloc ((long) sizeof (regs), "continuation"));
- CAR (rootcont) = tc7_contin;
- DYNENV (rootcont) = EOL;
- BASE (rootcont) = stack_start_ptr;
- listofnull = scm_cons (EOL, EOL);
- undefineds = scm_cons (SCM_UNDEFINED, EOL);
- CDR (undefineds) = undefineds;
- nullstr = scm_makstr (0L, 0);
- nullvect = scm_make_vector (INUM0, SCM_UNDEFINED);
- /* NEWCELL(nullvect);
- CAR(nullvect) = tc7_vector;
- SETCHARS(nullvect, NULL); */
- symhash = scm_make_vector ((SCM) MAKINUM (scm_symhash_dim), EOL);
- symhash_vars = scm_make_vector ((SCM) MAKINUM (scm_symhash_dim), EOL);
- scm_sysintern ("most-positive-fixnum", (SCM) MAKINUM (MOST_POSITIVE_FIXNUM));
- scm_sysintern ("most-negative-fixnum", (SCM) MAKINUM (MOST_NEGATIVE_FIXNUM));
- scm_sysintern ("*stdin*", def_inp);
- scm_sysintern ("*stdout*", def_outp);
- scm_sysintern ("*stderr*", def_errp);
- #ifdef BIGDIG
- scm_sysintern ("bignum-radix", MAKINUM (BIGRAD));
- #endif
- /* flo0 is now setup in scl.c */
- scm_bad_throw_vcell = scm_sysintern ("%%bad-throw", BOOL_F);
- }
-
-
- struct array
- {
- struct array * next;
- struct array * prev;
- int size;
- SCM elts[1];
- };
-
-
- static struct array * arrays;
-
- /* Not safely interrupted. */
- #ifdef __STDC__
- SCM *
- scm_mkarray (int size, int fillp)
- #else
- SCM *
- scm_mkarray (size, fillp)
- int size;
- int fillp;
- #endif
- {
- struct array * answer;
- answer = (struct array *)malloc (sizeof (*answer) + size * sizeof(SCM));
- if (!answer)
- return 0;
- answer->size = size;
- if (fillp)
- {
- int x;
- for (x = 0; x < size; ++x)
- answer->elts[x] = BOOL_F;
- }
- if (!arrays)
- {
- arrays = answer;
- answer->next = answer->prev = answer;
- }
- else
- {
- answer->next = arrays;
- answer->prev = arrays->prev;
- answer->next->prev = answer;
- answer->prev->next = answer;
- }
-
- return answer->elts;
- }
-
-
- /* Not safely implemented */
- #ifdef __STDC__
- void
- scm_free_array (SCM * elts)
- #else
- void
- scm_free_array (elts)
- SCM * elts;
- #endif
- {
- struct array * it;
- it = (struct array *) ((char *)elts - (int)(&((struct array *)0)->elts));
- if (it == arrays)
- {
- if (it == it->next)
- arrays = 0;
- else
- arrays = it->next;
- }
- it->next->prev = it->prev;
- it->prev->next = it->next;
- free ((char *)it);
- }
-
-
- #ifdef __STDC__
- void
- scm_mark_arrays (void)
- #else
- void
- scm_mark_arrays ()
- #endif
- {
- struct array * pos;
- pos = arrays;
- if (!pos)
- return;
- do
- {
- int x;
- int size;
- SCM * elts;
- size = pos->size;
- elts = pos->elts;
- for (x = 0; x < size; ++x)
- scm_gc_mark (elts[x]);
- pos = pos->next;
- } while (pos != arrays);
- }
-
-
- PROC (s_object_address, "object-address", 1, 0, 0, scm_object_addr);
- SCM
- scm_object_addr (obj)
- SCM obj;
- {
- return scm_ulong2num ((unsigned long)obj);
- }
-
- PROC (s_gc, "gc", 0, 0, 0, scm_gc);
- #ifdef __STDC__
- SCM
- scm_gc (void)
- #else
- SCM
- scm_gc ()
- #endif
- {
- DEFER_INTS;
- scm_igc ("call");
- ALLOW_INTS;
- return UNSPECIFIED;
- }
-
-
- #ifdef __STDC__
- void
- scm_remember (SCM * ptr)
- #else
- void
- scm_remember (ptr)
- SCM * ptr;
- #endif
- {}
-
-
-
-
- #ifdef __STDC__
- void
- scm_init_gc (void)
- #else
- void
- scm_init_gc ()
- #endif
- {
- #include "gc.x"
- }
-
- /* See "marksweep.c" */
-